/**
 * @description 后台装修页面
 */

import '@/style/admin.less'

import { useEffect, useState, useRef } from "react";
import { useSearchParams } from "react-router-dom"
import { useImmer } from 'use-immer';
import { message, Spin } from "antd";

import { info, save } from "@/api/decoration";
import initStyleData from "@/utils/styleOptions";
import eventBus from "@/utils/eventBus";
import versionCheckAndUpdate from "@/utils/versionCheckAndUpdate";

// 初始默认数据
import defaultData from './data/index'

// 当前右侧属性的表单form实例
import { getAttrForm } from "@/utils/AttrForm";

// 顶部tab标签切换
import TabWrapper from "./TabWrapper/index";

// 右侧属性
import AttrWrapper from "./AttrWrapper/index";

// 页面
import PageWrapper from './PageWrapper'
import { initStyle } from "@/utils/style";

// updateFlag 强制更新的上下文
import { UpdateContextProvider } from '@/store/updateContext';

// 右侧属性的子组件
const tabs = [
  {
    key: 'login',
    label: '登录',
  },
  {
    key: 'register',
    label: '注册',
  },
  {
    key: 'header',
    label: '头部',
  },
  {
    key: 'menu',
    label: '菜单',
  },
  {
    key: 'breadcrumb',
    label: '面包屑',
  },
  {
    key: 'home',
    label: '首页',
  },
  {
    key: 'list',
    label: '内容区',
  },
  {
    key: 'add',
    label: '新增编辑',
  },
  {
    key: 'chart',
    label: '图表',
  },
]



function AdminPage() {
  const [params] = useSearchParams();
  let id = params.get('id')

  // ------------------------
  // ------模板数据-----------
  // ------------------------
  const [login, setLogin] = useImmer(null)
  const [register, setRegister] = useImmer(null)
  const [header, setHeader] = useImmer(null)
  const [menu, setMenu] = useImmer(null)
  const [breadcrumb, setBreadcrumb] = useImmer(null)
  const [home, setHome] = useImmer(null)
  const [list, setList] = useImmer(null)
  const [add, setAdd] = useImmer(null)
  const [chart, setChart] = useImmer(null)

  // 页面初始化
  const [isInit, setIsInit] = useState(false)

  // 顶部的tab，激活
  const [actKey, setActKey] = useState('login')

  // 顶部tab，是否隐藏
  const [hideTab, setHideTab] = useState(false)

  // 右侧属性，是否隐藏
  const [hideAttr, setHideAttr] = useState(true)
  // 右侧属性的位置: 左侧还是右侧
  const [isRightAttr, setIsRightAttr] = useState(true)

  // 图表装修ChartAttr的tab
  const [chartTap, setChartTap] = useState('line')

  // 切换tab
  let changeTab = (newKey) => {

    if (newKey == actKey) {
      return
    }

    // [1] 同步数据。 chart图表装修除外
    if (actKey != 'chart') {
      let attrForm = getAttrForm()

      // 新数据
      let formData = attrForm.getFieldsValue(true)

      // 找对应的修改方法
      let setFn = getSetFn(actKey)
      setFn(formData)
    }


    // [2] 切换
    setActKey(newKey)

    // [3] 隐藏头部tab
    setHideTab(true)
  }

  // 配置项有变化
  let onConfigEvent = (keys, newValue) => {

    // 找对应的修改方法
    let setFn = getSetFn(actKey)


    // keys是空数组，修改整个数据
    if (!keys.length) {
      setFn(newValue)
      return
    }

    // 非空数组，修改某个key的数据
    // 最后一个索引
    let finalIndex = keys.length - 1

    setFn(preData => {
      keys.reduce((pre, curKey, index) => {
        if (index === finalIndex) {
          // 赋值
          pre[curKey] = newValue

          return null
        }

        return pre[curKey]
      }, preData)
    })
  }

  // 保存事件
  let saveEvent = async () => {

    try {

      // 新数据，区分图表装修chart
      let formData
      if (actKey == 'chart') {
        formData = JSON.stringify(chart)
      } else {
        let attrForm = getAttrForm()
        formData = attrForm.getFieldsValue(true)
        formData = JSON.stringify(formData)
      }


      let data = {
        moduleName: actKey,
        customTemplateId: id,
        param: formData
      }
      await save(data)

      message.open({
        content: '保存成功',
        type: 'success'
      })
    } catch (error) {
      message.open({
        content: '保存失败',
        type: 'error'
      })
    }
  }

  // 根据actKey获取对应响应式数据set方法
  function getSetFn(actKey) {
    let setFn = null
    switch (actKey) {
      case 'login':
        setFn = setLogin
        break;

      case 'register':
        setFn = setRegister
        break;

      case 'header':
        setFn = setHeader
        break;

      case 'menu':
        setFn = setMenu
        break;

      case 'breadcrumb':
        setFn = setBreadcrumb
        break;

      case 'list':
        setFn = setList
        break;

      case 'add':
        setFn = setAdd
        break;

      case 'home':
        setFn = setHome
        break;

      case 'chart':
        setFn = setChart
        break;
    }

    return setFn
  }

  // 滑动事件
  useEffect(() => {

    // touch滑动事件，控制头部和右侧的显示隐藏
    let touchEvent = (direction) => {
      switch (direction) {
        case 'swipedown':
          setHideTab(false)
          break;

        case 'swipeup':
          setHideTab(true)
          break;

        case 'swiperight':
          // 右侧模式，向右滑，影藏
          // 左侧模式，向右滑，显示
          isRightAttr ? setHideAttr(true) : setHideAttr(false)
          break;

        case 'swipeleft':
          isRightAttr ? setHideAttr(false) : setHideAttr(true)
          break;
      }
    }
    eventBus.on('touch', touchEvent)

    return () => {
      eventBus.off('touch', touchEvent)
    }
  }, [isRightAttr])

  // 获取模板数据
  useEffect(() => {

    // 1. 样式的下拉选项
    initStyleData()

    // 2. 模板数据
    let actKeys = tabs.map(item => item.key)

    let promiseAll = actKeys.map(actKey => {

      return new Promise(async (resolve, reject) => {

        try {
          let res = await info(id, actKey)
          let newData = res?.data?.param

          if (newData) {
            newData = JSON.parse(newData)

            // 检测版本 + 更新新版本数据，原地修改newData数据
            actKey !== 'chart' && versionCheckAndUpdate(newData, defaultData[actKey])

          } else {

            // 空模板，使用默认数据
            newData = defaultData[actKey]
          }

          // 手动添加样式
          initStyle(actKey, newData)

          // 更新模板数据
          let setFn = getSetFn(actKey)
          setFn(newData)

          resolve()

        } catch (error) {
          reject(error.message)
        }

      })
    })

    Promise.all(promiseAll).then(() => {

      // 初始化成功
      setIsInit(true)
    }).catch((errMsg) => {
      // 初始化失败
      console.log(errMsg)
    })

  }, [])

  // 监听键盘事件

  useEffect(() => {
    let handleKeyDown = (event) => {

      // 检查是否按下了 Ctrl + S
      if (event.ctrlKey && event.keyCode === 83) {
        event.preventDefault(); // 阻止默认的保存行为
        saveEvent()
      }

    }

    window.addEventListener('keydown', handleKeyDown)

    return () => {
      window.removeEventListener('keydown', handleKeyDown)
    }
  }, [actKey, chart])

  return (
    <>
      {/* 顶部tab */}
      <TabWrapper hide={hideTab} tabs={tabs} actKey={actKey} onTabChange={changeTab} saveEvent={saveEvent} />

      {
        isInit ?
          (
            <>
              {/* 激活的页面 */}
              <PageWrapper
                actKey={actKey}
                chartTap={chartTap}
                login={login}
                register={register}
                header={header}
                menu={menu}
                breadcrumb={breadcrumb}
                list={list}
                add={add}
                home={home}
                chart={chart}

              />


              {/* 右侧属性 */}
              <UpdateContextProvider>
                <div className={`attr-wrapper ${isRightAttr ? 'right' : 'left'} ${hideAttr ? 'hide' : ''}`}>
                  <AttrWrapper
                    actKey={actKey}
                    onConfigEvent={onConfigEvent}
                    setIsRightAttr={setIsRightAttr}
                    setChartTap={setChartTap}
                    chartTap={chartTap}
                    id={id}
                    login={login}
                    register={register}
                    header={header}
                    menu={menu}
                    breadcrumb={breadcrumb}
                    list={list}
                    add={add}
                    home={home}
                    chart={chart}
                  />
                </div>
              </UpdateContextProvider>

            </>
          )

          :

          <Spin tip='加载数据中...' fullscreen />
      }


    </>
  )
}

export default AdminPage